'use strict';

const uniConfig = require('uni-config-center');
const uidConfig = uniConfig({
	pluginId: 'uni-id'
});

const uidObj = require('uni-id');
const uidPay = require('uni-pay');
const {
	Controller
} = require('uni-cloud-router');

const dbcmd = uniCloud.database().command;

module.exports = class OrderAftersaleController extends Controller {
	
	/**
	 * 申请售后 - 1退款 | 2退货 | 3换货
	 * 
	 * 售后几种场景 scene
	 * 	1退款
	 * 	101 ['待发货'] 状态下整单商品申请退款，订单状态更改为 售后中
	 * 	102 ['待发货', '待收货'] 状态下剩余商品申请退款，订单状态更改为 售后中
	 * 	103 ['待发货', '待收货'] 状态下部分商品申请退款，订单状态不变
	 * 
	 * 	2退货
	 * 	201 ['待收货', '待评价', '已完成'] 状态下整单商品申请退货，订单状态更改为 售后中
	 * 	202 ['待收货', '待评价', '已完成'] 状态下剩余商品申请退货，订单状态更改为 售后中
	 * 	203 ['待收货', '待评价', '已完成'] 状态下部分商品申请退货，订单状态不变
	 * 
	 * 	3换货
	 * 	301 ['待评价', '已完成'] 状态下整单商品申请换货，订单状态更改为 售后中
	 * 	302 ['待评价', '已完成'] 状态下剩余商品申请换货，订单状态更改为 售后中
	 * 	303 ['待评价', '已完成'] 状态下部分商品申请换货，订单状态不变
	 * 
	 **/
	async applySubmit() {
		const response = {
			code: 1
		};
		
		const start = Date.now();
		const nowdate = start;
		const {
			order_id,
			goods_id,
			goods_sku_id,
			goods_state,
			refund_way,
			refund_amount,
			return_way,
			exchange_addr,
			reason,
			desc,
			imgs,
			type			// 退款 | 退货 | 换货
		} = this.ctx.data
		
		// 验证请求参数
		this.applyValidateReq(this.ctx.data);
		
		let uid = '';
		let user = {
			openid: '',
			name: '',
			headimg: '',
			mobile: ''
		};
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
				if (userRes.userInfo.wx_openid) {
					user.openid = userRes.userInfo.wx_openid['mp-weixin'];
				}
				user.name = userRes.userInfo.nickname || userRes.userInfo.username;
				user.headimg = userRes.userInfo.avatar;
				user.mobile = userRes.userInfo.mobile || '';
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		// 验证售后订单
		const {
			order,
			orderDetails
		} = await this.applyValidateOrder(this.ctx.data, uid);
		
		// 获取售后场景
		const { 
			scene: aftersaleScene, 
			desc: aftersaleSceneDesc 
		} = this.getAftersaleScene(this.ctx.data, order, orderDetails);
		// 获取退款金额
		const refundAmount = this.getAftersaleRefundAmount(aftersaleScene, order, orderDetails);
		
		
		// 写入申请售后数据
		const aftersaleRes = await this.db.collection('usemall-order-aftersale').add({
			order_id,
			goods_id: goods_id || '',
			goods_sku_id: goods_sku_id || '',
			
			refund_way,
			refund_amount: refundAmount,
			return_way,
			exchange_addr,
			
			member_guid: uid,
			member_name: user.name,
			member_headimg: user.headimg,
			goods_state: goods_state || '已收到货',
			reason,
			desc,
			imgs,
			remark: `申请${type}`,
			type,
			// 售后场景
			scene: aftersaleScene,
			scene_desc: aftersaleSceneDesc,
			logs: [{
				type: '提交申请',
				remark: `提交申请${type}`,
				ip: this.ctx.context.CLIENTIP,
				uid: uid,
				uname: user.uname,
				time: nowdate
			}],
			version: 1,
			state: '待处理',
			sub_state: '',
			is_delete: 0,
			create_uid: uid,
			create_time: nowdate,
			create_uname: user.name
		});
		
		if (!(aftersaleRes && aftersaleRes.id)) {
			response.msg = '申请售后失败';
			return response;
		}
		
		
		try {
			const msg_req = {
				title: `${user.name} 申请${type} - ${aftersaleScene}`,
				type: `申请${type}`,
				reason: `原因：${reason}`,
				status: `待处理`,
				remark: ''
			};
			switch (type){
				case '退款':
					msg_req.scene = 201;
					break;
				case '退货':
					msg_req.scene = 202;
					break;
				case '换货':
					msg_req.scene = 203;
					break;
			}
			
			// 消息通知
			// 不需要 await，只需发送请求即可
			const messageNotifyUrl = `${uidConfig.config('message-notify.url')}/aftersale`;
			if (messageNotifyUrl.indexOf('http') === 0) {
				uniCloud.httpclient.request(messageNotifyUrl, {
					method: 'post',
					headers: {
						'message-notify-key': uidConfig.config('message-notify.key')
					},
					data: {
						id: aftersaleRes.id,
						...msg_req
					},
					timeout: 30 * 1000,
					contentType: 'json',
					dataType: 'json'
				});
			}
		} catch(e) {
			console.log('message-notify err', e);
		}
		
		// 当前售后数
		const aftersaleCnt = orderDetails.length || 1;
		// 订单修改数据
		const updateOrderObj = {
			// 售后状态 0未售后 1售后中 2已售后 99禁止售后
			aftersale_state: 1,
			aftersale_id: aftersaleRes.id,
			aftersale_pre_state: order.state,
			
			aftersale_cnt: dbcmd.inc(aftersaleCnt)
		};
		
		// 整单都售后的情况下才需要修改为 售后中
		if ([101, 201, 301].includes(aftersaleScene)) {
			// 整单发生售后
			updateOrderObj.state = '售后中';
			if ([101, 201].includes(aftersaleScene)) {
				// 整单退款
				updateOrderObj.order_refund_state = '待处理';
			}
			
			updateOrderObj.order_aftersale = {
				type: type,
				reason: reason,
				desc: desc,
				amount: refundAmount,
				time: nowdate,
				remark: ''
			};
		}
		
		// 剩余商品申请售后情况下 订单状态更改为 售后中
		if ([102, 202, 302].includes(aftersaleScene)) {
			// 整单售后
			updateOrderObj.state = '售后中';
		}
		
		// 写入订单日志
		await this.db.collection('usemall-order-log').add({
			order_id: order_id,
			log_type: `申请${type}`,
			current_state: '售后中',
			prev_state: order.state,
			ip: this.ctx.context.CLIENTIP,
			is_delete: 0,
			create_uid: uid,
			create_time: nowdate,
			create_uname: user.name
		});
		// 修改订单申请售后数据
		await this.db.collection('usemall-order').doc(order._id).update({
			last_modify_time: nowdate,
			last_modify_uid: uid,
			last_modify_uname: user.name,
			
			...updateOrderObj
		});
		
		if (orderDetails.length) {
			for (let i = 0; i < orderDetails.length; i++) {
				const orderDetail = orderDetails[i];
				
				// 整单退款 || 商品ID、商品SKU
				if (aftersaleScene == 101 || (orderDetail.goods_id === goods_id && (orderDetail.goods_sku_id === goods_sku_id || !goods_sku_id))) {
					// 修改订单商品售后数据
					await this.db.collection('usemall-order-detail').doc(orderDetail._id).update({
						aftersale: {
							state: '待处理',
							type: type,
							reason: reason,
							desc: desc,
							amount: refundAmount,
							time: nowdate,
							remark: ''
						},
						// 售后状态 0未售后 1售后中 2已售后 99禁止售后
						aftersale_state: 1,
						aftersale_id: aftersaleRes.id,
						
						last_modify_time: nowdate,
						last_modify_uid: uid,
						last_modify_uname: user.name
					});
				}
			}
		}
		
		
		const end = Date.now();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.time = `耗时：${end - start}ms`;
		response.msg = '申请成功';
		return response;
	}
	// 验证请求参数
	applyValidateReq(req) {
		const {
			order_id,
			goods_id,
			goods_sku_id,
			goods_state,
			refund_way,
			refund_amount,
			return_way,
			exchange_addr,
			reason,
			desc,
			imgs,
			type			// 退款 | 退货 | 换货
		} = req;
		
		if (!type) {
			this.throw(`请选择售后类型`);
		}
		if (!['退款', '退货', '换货'].includes(type)) {
			this.throw(`售后类型[${type}]不支持`);
		}
		if (!reason) {
			this.throw(`请选择售后原因`);
		}
		if (!order_id) {
			this.throw(`请选择申请售后的订单`);
		}
		if (['退货', '换货'].includes(type) && !goods_id) {
			this.throw(`请选择申请售后的商品`);
		}
		
		switch (type){
			case '退款':
				if (!goods_state) this.throw(`请选择货物状态`);
				if (!refund_amount) this.throw(`申请退款金额需大于0`);
				break;
			case '退货':
				break;
			case '换货':
				if (!(exchange_addr && exchange_addr.addr)) this.throw(`请选择换货的收货地址`);
				break;
		}
		
	}
	// 验证售后订单
	async applyValidateOrder(req, uid) {
		const {
			order_id,
			goods_id,
			goods_sku_id,
			goods_state,
			type			// 退款 | 退货 | 换货
		} = req;
		
		const orderWhere = {
			is_delete: 0,
			create_uid: uid,
			state: '',
			order_id: order_id
		};
		
		switch (type) {
			case '退款':
				orderWhere.state = this.db.command.in(['待发货', '待收货', '售后中']);
				break;
			case '退货':
				orderWhere.state = this.db.command.in(['待收货', '待评价', '已完成', '售后中']);
				break;
			case '换货':
				orderWhere.state = this.db.command.in(['待评价', '已完成', '售后中']);
				break;
		}
		
		const orderRes = await this.db.collection('usemall-order')
			.where(orderWhere)
			.field({
				order_actural_paid: true,
				aftersale_state: true,
				aftersale_cnt: true,
				order_sku_cnt: true,
				state: true,
				create_uid: true
			})
			.get();
		
		if (!(orderRes.data && orderRes.data.length == 1)) {
			this.throw(`申请售后订单不存在`);
		}
		// 售后订单
		const [order] = orderRes.data;
		
		if (order.aftersale_state == 99) {
			this.throw(`当前订单已超过售后时间`);
		}
		
		const orderDetailWhere = {
			order_id: order_id
		};
		if (goods_id) {
			orderDetailWhere.goods_id = goods_id;
		}
		if (goods_sku_id) {
			orderDetailWhere.goods_sku_id = goods_sku_id;
		}
		
		const orderDetailsRes = await this.db.collection('usemall-order-detail')
			.where(orderDetailWhere)
			.get();
		// 订单详情
		const orderDetails = orderDetailsRes.data || [];
		
		// 验证申请售后商品是否存在
		let goodsIdx = 0;
		if (goods_id) {
			goodsIdx = orderDetails.findIndex(x => x.goods_id === goods_id);
		} 
		if (goods_sku_id) {
			goodsIdx = orderDetails.findIndex(x => x.goods_id === goods_id && x.goods_sku_id === goods_sku_id);
		}
		
		if (goodsIdx === -1) {
			this.throw(`申请售后商品不存在`);
		}
		
		// 判断售后是否已提交
		const aftersaleExistWhere = orderDetailWhere;
		const aftersaleRes = await this.db.collection('usemall-order-aftersale').where({
			state: '待处理',
			...aftersaleExistWhere
		}).field({
			order_id: true,
			state: true
		}).get();
		
		if (aftersaleRes.data && aftersaleRes.data.length) {
			this.throw(`申请售后待处理中`);
		}
		
		return {
			order,
			orderDetails
		};
	}
	// 获取售后场景
	getAftersaleScene(req, order, orderDetails) {
		const {
			goods_id,
			type
		} = req;
		
		// 单SKU订单类型
		const singleOrderType = order.order_sku_cnt === 1;
		// 未售后数量 = 购买数 - 售后数
		const unAftersaleCnt = order.order_sku_cnt - (order.aftersale_cnt || 0);
		
		// 售后场景ID
		const aftersaleScene = {
			scene: 0,
			desc: ''
		};
		
		if (singleOrderType) {
			// 单SKU整单售后情况
			switch (type){
				case '退款':
					aftersaleScene.scene = 101;
					aftersaleScene.desc = '101-整单退款';
					break;
				case '退货':
					aftersaleScene.scene = 201;
					aftersaleScene.desc = '201-整单退货';
					break;
				case '换货':
					aftersaleScene.scene = 301;
					aftersaleScene.desc = '301-整单换货';
					break;
			}
		} else if (unAftersaleCnt === 1 || unAftersaleCnt === orderDetails.length) {
			// 多SKU下单售后情况 剩余未售后的商品申请售后
			switch (type){
				case '退款':
					aftersaleScene.scene = 102;
					aftersaleScene.desc = '102-剩余商品退款';
					break;
				case '退货':
					aftersaleScene.scene = 202;
					aftersaleScene.desc = '202-剩余商品退货';
					break;
				case '换货':
					aftersaleScene.scene = 302;
					aftersaleScene.desc = '302-剩余商品换货';
					break;
			}
		} else {
			// 多SKU下单售后情况 部分商品申请售后
			switch (type){
				case '退款':
					// 存在商品ID '剩余商品 | 部分商品' 场景下
					if (goods_id) {
						// 部分商品退款
						aftersaleScene.scene = 103;
						aftersaleScene.desc = '103-部分商品退款';
						break;
					} 
					
					// 整单申请退款 待发货订单整单申请退款情况
					aftersaleScene.scene = 101;
					aftersaleScene.desc = '101-整单退款';
					break;
				case '退货':
					aftersaleScene.scene = 203;
					aftersaleScene.desc = '203-部分商品退货';
					break;
				case '换货':
					aftersaleScene.scene = 303;
					aftersaleScene.desc = '303-部分商品换退';
					break;
			}
		}
		
		// 待发货订单 为整单退款场景
		if (order.state === '待发货') {
			aftersaleScene.scene = 101;
			aftersaleScene.desc = '101-整单退款';
		}
		
		return aftersaleScene;
	}
	/**
	 * 获取退款金额
	 * scene
	 * 退款 101整单退款 102剩余商品退款 103部分商品退款
	 * 退货 201整单退货 202剩余商品退货 203部分商品退货
	 * 换货 301整单换货 302剩余商品换货 303部分商品换货
	 * */ 
	getAftersaleRefundAmount(scene, order, orderDetails) {
		let refundAmount = 0;
		
		if ([101, 201].includes(scene)) {
			// 整单退款|退货退款 退款金额 = 实付款金额
			refundAmount = order.order_actural_paid;
			return refundAmount;
		}
		
		if ([301, 302, 303].includes(scene)) {
			// 换货场景下 退款为0
			return refundAmount;
		}
		
		orderDetails.forEach(x => {
			// 剩余商品|部分商品 退款金额 += 商品付款金额
			refundAmount += x.goods_amount;
		});
		
		return refundAmount;
	}
	
	// 售后 退货 | 换货 自行寄回
	async selfExpress() {
		const response = {
			code: 1
		};
		
		const start = Date.now();
		const nowdate = start;
		
		const {
			aftersale_id,
			no,
			com,
			express,
			remark
		} = this.ctx.data;
		
		let uid = '';
		let uname = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
				uname = userRes.userInfo.nickname || userRes.userInfo.username;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		const aftersaleRes = await this.db.collection('usemall-order-aftersale').where({
			_id: aftersale_id,
			is_delete: 0,
			create_uid: uid
		})
		.field({
			logs: false
		})
		.get();
		
		const [aftersale] = aftersaleRes.data;
		
		if (!(aftersale && aftersale._id)) {
			response.msg = '售后订单不存在';
			return response;
		}
		
		// 判断订单状态是否结束
		if (['已完成', '已取消', '已拒绝'].includes(aftersale.state)) {
			response.msg = `售后${aftersale.state}`;
			return response;
		}
		
		let phone = '';
		if (aftersale && aftersale.return_addr) {
			phone = aftersale.return_addr.mobile;
		}
		
		// 修改售后数据
		const updateRes = await this.db.collection('usemall-order-aftersale').doc(aftersale_id)
			.update({
				return_express: {
					express,
					phone,
					com,
					no,
					remark
				},
				
				state: '待卖家处理',
				sub_state: '待收货',
				remark: `已寄${aftersale.type}商品，待商家收货`,
				
				logs: this.db.command.push({
					type: `${aftersale.type}已寄`,
					remark: remark || `已快递邮寄${aftersale.type}商品`,
					ip: this.ctx.context.CLIENTIP,
					uid: uid,
					uname: uname,
					time: nowdate
				})
			});
			
		// 修改成功
		if (updateRes && updateRes.updated === 1) {
			// 修改售后订单详情数据 待收货
			await this.db.collection('usemall-order-detail').where({
					order_id: aftersale.order_id,
					aftersale_id: aftersale._id,
					aftersale_state: 1
				}).update({
					aftersale: {
						state: '待收货'
					}
				});
			
			const orderRes = await this.db.collection('usemall-order').where({ 
					order_id: aftersale.order_id
				}).field({ 
					state: true,
					order_member_name: true
				}).get();
			const [order] = orderRes.data;
			
			// 写入订单日志
			await this.db.collection('usemall-order-log').add({
				order_id: aftersale.order_id,
				log_type: `${aftersale.type}已寄`,
				current_state: order.state,
				prev_state: order.state,
				ip: this.ctx.context.CLIENTIP,
				is_delete: 0,
				create_uid: uid,
				create_time: nowdate,
				create_uname: order.order_member_name
			});
		}
		
		const end = Date.now();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.duration = `耗时：${end - start}ms`;
		return response;
	}
	
	// 快递公司列表
	async expressList() {
		const response = {
			code: 1,
			datas: []
		};
		
		const {
			
		} = this.ctx.data;
		
		const dataRes = await this.db.collection('usemall-order-express').where({
				is_delete: 0,
				state: 1
			})
			.field({
				name: true,
				encoding: true
			})
			.orderBy('sort', 'asc')
			.get();
		
		response.code = 0;
		response.datas = dataRes.data;
		return response;
	}
	
	// 售后详情
	async detail() {
		const response = {
			code: 1,
			order: {},
			order_detail: []
		};

		const start = Date.now();
		const nowdate = start;
		const {
			aftersale_id
		} = this.ctx.data;
		let uid = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		// 订单时间
		let order_time = 0;
		// 配置时间
		let order_config_time = 0;
		
		
		const aftersaleRes = await this.db.collection('usemall-order-aftersale').where({
			_id: aftersale_id,
			is_delete: 0,
			create_uid: uid
		}).get();
		
		const [aftersale] = aftersaleRes.data;
		
		if (!(aftersale && aftersale._id)) {
			response.msg = `售后不存在或已删除`;
			return response;
		}
		
		// 订单ID
		const order_id = aftersale.order_id;
		
		// 订单详情 where
		const orderDetailWhere = {
			order_id: order_id
		};
		if (aftersale.goods_id) orderDetailWhere.goods_id = aftersale.goods_id;
		if (aftersale.goods_sku_id) orderDetailWhere.goods_sku_id = aftersale.goods_sku_id;
		
		const order = this.db.collection('usemall-order').where({
			order_id: order_id,
			create_uid: uid
		}).get();
		const order_detail = this.db.collection('usemall-order-detail').where(orderDetailWhere).get();
		const orderConfigRes = this.db.collection('usemall-order-parameter').limit(1).get();
		
		const datas = await Promise.all([order, order_detail, orderConfigRes]);
		
		response.aftersale = aftersale;
		[response.order] = datas[0] && datas[0].data;
		response.order_detail = datas[1] && datas[1].data;
		
		if (!(response.order && response.order._id)) {
			response.msg = `售后订单[${order_id}]不存在`;
			return response;
		}
		
		// 订单配置
		const [orderConfig] = datas[2] && datas[2].data;
		response.order_config = orderConfig;
		
		try {
			switch (response.aftersale.state) {
				case '待处理':
					response.time_remaining = parseInt((response.order.order_expire_time - Date.now()) / 1000);
					
					break;
				case '待买家处理':
					response.time_remaining = parseInt((response.order.order_expire_time - Date.now()) / 1000);
					
					break;
				case '待卖家处理':
					response.time_remaining = parseInt((response.order.order_expire_time - Date.now()) / 1000);
					
					break;
			}
		
		} catch(e) {
			response.msg = e.message;
		}
		
		const end = Date.now();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.duration = `耗时：${end - start}ms`;
		return response;
	}

	// 售后列表
	async list() {
		const response = {
			code: 1,
			datas: []
		};

		const start = Date.now();
		const {
			page,
			rows,
			state
		} = this.ctx.data;
		let uid = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		const where_obj = {
			is_delete: 0,
			create_uid: uid
		};
		
		switch (state){
			case '售后中':
				where_obj.state = dbcmd.in(['待处理', '待买家处理', '待卖家处理']);
				break;
			case '已售后':
				where_obj.state = dbcmd.in(['已拒绝', '已完成']);
				break;
			case '已取消':
				where_obj.state = dbcmd.in(['已取消']);
				break;
		}
		
		const aftersaleRes = await this.db.collection('usemall-order-aftersale')
			.where(where_obj)
			.orderBy('create_time', 'desc')
			.skip((page - 1) * rows)
			.limit(rows)
			.get();
		
		const datas = [];
		const ids = aftersaleRes.data.map(x => x.order_id);
		
		const orderRes = await this.db.collection('usemall-order')
			.where({
				create_uid: uid,
				order_id: dbcmd.in(ids)
			})
			.orderBy('create_time', 'desc')
			.skip((page - 1) * rows)
			.limit(rows)
			.get();
		
		const orderDetailsRes = await this.db.collection('usemall-order-detail').where({
			order_id: dbcmd.in(ids)
		}).get();

		aftersaleRes.data.forEach(x => {
			datas.push({
				order: orderRes.data.find(d => d.order_id == x.order_id),
				orderDetails: orderDetailsRes.data.filter(d => d.order_id == x.order_id && (d.goods_id == x.goods_id || !x.goods_id) && (d.goods_sku_id == x.goods_sku_id || !x.goods_sku_id)),
				aftersale: x
			})
		});
		response.datas = datas;

		const end = Date.now();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.duration = `耗时：${end - start}ms`;
		return response;
	}
	// 取消售后
	async cancel() {
		const response = {
			code: 1,
		};
		const start = Date.now();
		const nowdate = start;
		const {
			aftersale_id
		} = this.ctx.data;
		
		let uid = '';
		let uname = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
				uname = userRes.userInfo.nickname || userRes.userInfo.username;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		const aftersaleRes = await this.db.collection('usemall-order-aftersale').where({
			_id: aftersale_id,
			is_delete: 0,
			create_uid: uid
		})
		.field({
			logs: false
		})
		.get();
		
		const [aftersale] = aftersaleRes.data;
		
		if (!(aftersale && aftersale._id)) {
			response.msg = '售后订单不存在';
			return response;
		}
		
		// 判断订单状态是否结束
		if (['已完成', '已取消', '已拒绝'].includes(aftersale.state)) {
			response.msg = `售后${aftersale.state}`;
			return response;
		}
		
		// 取消订单
		response.datas = await this.__cancelOrderAftersale(uid, uname, aftersale, '取消' + aftersale.type);
		
		const end = Date.now();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.duration = `耗时：${end - start}ms`;
		return response;
	}
	// 取消订单售后服务
	async __cancelOrderAftersale(uid, uname, aftersale, remark) {
		
		// aftersale.state 		状态 	待处理|待买家处理|待卖家处理|已拒绝|已完成|已取消
		// aftersale.sub_state 	子状态 	待寄回|待收货|待发货|待签收
		if (!(aftersale.state === '待处理' || aftersale.sub_state === '待寄回')) {
			this.throw(`当前售后[${aftersale.state}]`);
		}
		
		/**
		 * 1. 售后状态修改为 已取消、子状态 置空、备注说明
		 * 2. 修改售后中订单状态为 prev 状态值
		 * 3. 修改订单详情售后状态
		 */
		
		const nowdate = Date.now();
		const state = '已取消';
		
		const updateRes = await this.db.collection('usemall-order-aftersale')
			.doc(aftersale._id)
			.update({
				state: state,
				sub_state: '',
				logs: this.db.command.push({
					type: `取消${aftersale.type}`,
					remark: remark || `取消申请${aftersale.type}`,
					ip: this.ctx.context.CLIENTIP,
					uid: uid,
					uname: uname,
					time: nowdate
				}),
				
				remark: remark,
				last_modify_time: nowdate,
				last_modify_uid: uid,
			});
		
		if (updateRes && updateRes.updated) {
			// 取消售后成功
			// 查询售后订单
			const orderRes = await this.db.collection('usemall-order').where({
					order_id: aftersale.order_id
				})
				.field({
					state: true,
					aftersale_id: true,
					aftersale_state: true,
					aftersale_pre_state: true,
					aftersale_cnt: true,
					order_refund_state: true,
					
					order_id: true,
					create_uid: true,
					order_member_name: true,
					order_expire_time: true
				})
				.limit(1)
				.get();
			const [order] = orderRes.data;
			
			if (order && order._id) {
				order.aftersale_cnt -= 1;
				if (order.aftersale_cnt <= 0) order.aftersale_cnt = 0;
				
				const orderUpdateObj = {
					aftersale_state: order.aftersale_cnt ? order.aftersale_state : 0,
					aftersale_cnt: order.aftersale_cnt,
				};
				if (order.state == '售后中') {
					orderUpdateObj.state = order.aftersale_pre_state;
					orderUpdateObj.aftersale_pre_state = '';
					orderUpdateObj.order_aftersale = {
						state: ''
					};
				} 
				if (order.order_refund_state == '待处理') {
					orderUpdateObj.order_refund_state = '';
				}
				
				// 修改售后中订单状态、售后状态
				await this.db.collection('usemall-order')
					.doc(order._id)
					.update({
						...orderUpdateObj,
						
						last_modify_time: nowdate,
						last_modify_uid: uid
					});
					
				if (order.state == '售后中') {
					// 写入日志
					await this.db.collection('usemall-order-log').add({
						order_id: order.order_id,
						log_type: `取消${aftersale.type}`,
						current_state: order.aftersale_pre_state,
						prev_state: '售后中',
						remark: `取消${aftersale.type}申请，状态修改为${order.aftersale_pre_state}`,
						ip: this.ctx.context.CLIENTIP,
						is_delete: 0,
						create_uid: uid,
						create_time: nowdate
					});
				} else {
					// 写入日志
					await this.db.collection('usemall-order-log').add({
						order_id: order.order_id,
						log_type: `取消${aftersale.type}`,
						current_state: order.state,
						prev_state: order.state,
						remark: `取消${aftersale.type}申请`,
						ip: this.ctx.context.CLIENTIP,
						is_delete: 0,
						create_uid: uid,
						create_time: nowdate
					});
				}
			} 
			
			// 修改订单明细
			const orderDetailWhere = {
				order_id: aftersale.order_id,
				aftersale_id: aftersale._id,
				aftersale_state: 1
			};
			
			// 修改售后中订单状态、售后状态
			await this.db.collection('usemall-order-detail')
				.where(orderDetailWhere)
				.update({
					aftersale_state: 0,
					aftersale: {
						state: state
					}
				});
		}
		
		return updateRes;
	}

	// 确认收货
	async received() {
		const response = {
			code: 1
		};
		
		const start = Date.now();
		const nowdate = start;
		
		const {
			aftersale_id
		} = this.ctx.data;
		
		let uid = '';
		let uname = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
				uname = userRes.userInfo.nickname || userRes.userInfo.username;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		const aftersaleRes = await this.db.collection('usemall-order-aftersale').where({
			_id: aftersale_id,
			is_delete: 0,
			create_uid: uid
		})
		.field({
			logs: false
		})
		.get();
		
		const [aftersale] = aftersaleRes.data;
		
		if (!(aftersale && aftersale._id)) {
			response.msg = '售后订单不存在';
			return response;
		}
		
		// 判断订单状态是否结束
		if (['已完成', '已取消', '已拒绝'].includes(aftersale.state)) {
			response.msg = `售后${aftersale.state}`;
			return response;
		}
		
		let remark = `商品已确认收货，${aftersale.type}完成`;
		// 修改售后数据
		const updateRes = await this.db.collection('usemall-order-aftersale').doc(aftersale_id)
			.update({
				state: '已完成',
				sub_state: '',
				remark: remark,
				
				logs: this.db.command.push({
					type: `确认收货`,
					remark: remark,
					ip: this.ctx.context.CLIENTIP,
					uid: uid,
					uname: uname,
					time: nowdate
				})
			});
			
		// 修改成功
		if (updateRes && updateRes.updated === 1) {
			// 修改售后订单详情数据 已完成
			await this.db.collection('usemall-order-detail').where({
					order_id: aftersale.order_id,
					aftersale_id: aftersale._id,
					aftersale_state: 1
				}).update({
					aftersale_state: 2,
					aftersale: {
						state: '已完成'
					}
				});
			
			const orderDetailsRes = await this.db.collection('usemall-order-detail')
				.where({
					order_id: aftersale.order_id
				}).get();
			const orderDetails = orderDetailsRes.data;
			
			// 判断订单是否已售后完成
			const orderUpdateObj = {};
			if (aftersale.scene === 301) {
				// 整单申请换货场景
				// 已完成售后
				orderUpdateObj.state = '已完成';
				orderUpdateObj.aftersale_state = 2;
			} else if (orderDetails.length - 1 == orderDetails.filter(x => x.aftersale_state === 2).length) {
				// 整单已完成售后
				orderUpdateObj.state = '已完成';
				orderUpdateObj.aftersale_state = 2;
			}
			
			if (Object.keys(orderUpdateObj).length) {
				// 修改订单状态
				const orderUpdateRes = await this.db.collection('usemall-order')
					.where({
						order_id: aftersale.order_id,
						aftersale_state: 1
					})
					.update({
						...orderUpdateObj,
						
						last_modify_time: nowdate,
						last_modify_uid: uid
					});
				
				if (orderUpdateRes && orderUpdateRes.updated) {
					// 写入日志 
					await this.db.collection('usemall-order-log')
						.add({
							order_id: aftersale.order_id,
							log_type: `${aftersale.type}完成`,
							current_state: '已完成',
							prev_state: '售后中',
							remark: remark,
							ip: this.ctx.context.CLIENTIP,
							is_delete: 0,
							create_uid: uid,
							create_time: nowdate
						});
				}
			}
		}
		
		const end = Date.now();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.duration = `耗时：${end - start}ms`;
		return response;
	}

	// 删除售后
	async deleted() {
		const response = {
			code: 1,
		};
		
		const start = Date.now();
		const nowdate = start;
		
		const {
			aftersale_id,
		} = this.ctx.data;
		let uid = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		const where_obj = {
			_id: aftersale_id,
			is_delete: 0,
			create_uid: uid,
			state: this.db.command.in(['已取消', '已完成', '已拒绝'])
		};
		
		const updateRes = await this.db.collection('usemall-order-aftersale')
			.where(where_obj)
			.update({
				is_delete: 1,
				last_modify_time: nowdate,
				last_modify_uid: uid,
			})
			
		if (updateRes && updateRes.updated == 1) {
			response.datas = updateRes;
			response.code = 0;
		} else {
			response.msg = `当前售后禁止删除`;
		}
		
		const end = Date.now();
		console.log(`耗时：${end - start}ms`);
		response.duration = `耗时：${end - start}ms`;
		return response;
	}
	
	// 物流轨迹
	async express() {
		const response = {
			code: 1,
			msg: '物流轨迹查询失败'
		};
		const {
			aftersale_id,
			type	// 2售后退换货寄回 3售后换货寄出
		} = this.ctx.data;

		if (!aftersale_id) {
			response.msg = '售后ID不存在';
			return response;
		}
		let uid = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		// 查询订单数据
		const aftersaleRes = await this.db.collection('usemall-order-aftersale').where({
			_id: aftersale_id,
			create_uid: uid
		}).field({
			logs: false
		}).get();

		const [aftersale] = aftersaleRes.data;
		
		// 快递信息
		let express = {};
		
		switch (type) {
			case 2:
				// 买家 退货/换货 寄给卖家的快递信息
				express = aftersale.return_express;
				// 售后卖家收货 - 手机号
				express.phone = aftersale.return_addr.mobile;
				break;
			case 3:
				// 买家 换货 卖家寄出的快递信息
				express = aftersale.exchange_express;
				break;
		}
		
		if (!Object.keys(express).length) {
			response.msg = '快递单号不存在';
			return response;
		}

		// 调用快递100 实时快递查询接口
		const kd100Res = await this.service.express.kd100Query({
			"com": express.com || this.service.express.getKd100Com(express.com),
			"num": express.no,
			"phone": express.phone
		});
		response.datas = kd100Res;
		response.datas.company = express.express;
		response.msg = response.datas.message;

		if (response.datas && response.datas.message == "ok") {
			response.code = 0;
		}

		return response;
	}

	// float 格式化，防止 js 精度丢失
	format_float(number) {
		number = parseFloat(number);
		if (isNaN(number)) return number;
		
		number = parseInt(number.toFixed(2) * 100);
		
		return number / 100;
	}

}
